ti: k3: drivers: ti_sci: Add processor status wait API
authorAndrew F. Davis <[email protected]>
Tue, 18 Dec 2018 19:21:12 +0000 (13:21 -0600)
committerAndrew F. Davis <[email protected]>
Mon, 21 Jan 2019 19:07:07 +0000 (13:07 -0600)
This TI-SCI API can be used wait for a set of processor status flags to
be set or cleared. The flags are processor type specific. This command
will not return ACK until the specified status is met. NACK will be
returned after the timeout elapses or on error.

Signed-off-by: Andrew F. Davis <[email protected]>
Acked-by: Nishanth Menon <[email protected]>
plat/ti/k3/common/drivers/ti_sci/ti_sci.c
plat/ti/k3/common/drivers/ti_sci/ti_sci.h
plat/ti/k3/common/drivers/ti_sci/ti_sci_protocol.h

index b211bdf60bf7163f8718fb152f6ca98035b47010..f6d71a0a4c7c095301691741dfca63291a5425a9 100644 (file)
@@ -1458,6 +1458,87 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
        return 0;
 }
 
+/**
+ * ti_sci_proc_wait_boot_status() - Wait for a processor boot status
+ *
+ * @proc_id:                   Processor ID this request is for
+ * @num_wait_iterations                Total number of iterations we will check before
+ *                             we will timeout and give up
+ * @num_match_iterations       How many iterations should we have continued
+ *                             status to account for status bits glitching.
+ *                             This is to make sure that match occurs for
+ *                             consecutive checks. This implies that the
+ *                             worst case should consider that the stable
+ *                             time should at the worst be num_wait_iterations
+ *                             num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us     Specifies how long to wait (in micro seconds)
+ *                             between each status checks. This is the minimum
+ *                             duration, and overhead of register reads and
+ *                             checks are on top of this and can vary based on
+ *                             varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ *                             before the very first check in the first
+ *                             iteration of status check loop. This is the
+ *                             minimum duration, and overhead of register
+ *                             reads and checks are.
+ * @status_flags_1_set_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 0.
+ *
+ * Return: 0 if all goes well, else appropriate error message
+ */
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+                                uint8_t num_match_iterations,
+                                uint8_t delay_per_iteration_us,
+                                uint8_t delay_before_iterations_us,
+                                uint32_t status_flags_1_set_all_wait,
+                                uint32_t status_flags_1_set_any_wait,
+                                uint32_t status_flags_1_clr_all_wait,
+                                uint32_t status_flags_1_clr_any_wait)
+{
+       struct ti_sci_msg_req_wait_proc_boot_status req;
+       struct ti_sci_msg_hdr resp;
+
+       struct ti_sci_xfer xfer;
+       int ret;
+
+       ret = ti_sci_setup_one_xfer(TISCI_MSG_WAIT_PROC_BOOT_STATUS,
+                                   TI_SCI_FLAG_REQ_ACK_ON_PROCESSED,
+                                   &req, sizeof(req),
+                                   &resp, sizeof(resp),
+                                   &xfer);
+       if (ret) {
+               ERROR("Message alloc failed (%d)\n", ret);
+               return ret;
+       }
+
+       req.processor_id = proc_id;
+       req.num_wait_iterations = num_wait_iterations;
+       req.num_match_iterations = num_match_iterations;
+       req.delay_per_iteration_us = delay_per_iteration_us;
+       req.delay_before_iterations_us = delay_before_iterations_us;
+       req.status_flags_1_set_all_wait = status_flags_1_set_all_wait;
+       req.status_flags_1_set_any_wait = status_flags_1_set_any_wait;
+       req.status_flags_1_clr_all_wait = status_flags_1_clr_all_wait;
+       req.status_flags_1_clr_any_wait = status_flags_1_clr_any_wait;
+
+       ret = ti_sci_do_xfer(&xfer);
+       if (ret) {
+               ERROR("Transfer send failed (%d)\n", ret);
+               return ret;
+       }
+
+       if (!ti_sci_is_response_ack(&resp))
+               return -ENODEV;
+
+       return 0;
+}
+
 /**
  * ti_sci_init() - Basic initialization
  *
index 1176b00f47b049b82d27249f3e618027395472f5..91f8645731dc868641e4bbebd1cf452704df39ef 100644 (file)
@@ -179,6 +179,7 @@ int ti_sci_core_reboot(void);
  *                                 and then set the processor configuration flags.
  *              @cert_addr: Memory address at which payload image certificate is located.
  * - ti_sci_proc_get_boot_status - Command to get the processor boot status
+ * - ti_sci_proc_wait_boot_status - Command to wait for a processor boot status
  *
  * NOTE: for all these functions, the following are generic in nature:
  * @proc_id:   Processor ID
@@ -197,6 +198,14 @@ int ti_sci_proc_get_boot_status(uint8_t proc_id, uint64_t *bv,
                                uint32_t *cfg_flags,
                                uint32_t *ctrl_flags,
                                uint32_t *sts_flags);
+int ti_sci_proc_wait_boot_status(uint8_t proc_id, uint8_t num_wait_iterations,
+                                uint8_t num_match_iterations,
+                                uint8_t delay_per_iteration_us,
+                                uint8_t delay_before_iterations_us,
+                                uint32_t status_flags_1_set_all_wait,
+                                uint32_t status_flags_1_set_any_wait,
+                                uint32_t status_flags_1_clr_all_wait,
+                                uint32_t status_flags_1_clr_any_wait);
 
 /**
  * ti_sci_init() - Basic initialization
index c6d76d7ea168b862bbf23667aa0a64cbb3e2f2eb..a921e512a8fa39738afd2439278681074d6044a7 100644 (file)
@@ -46,6 +46,7 @@
 #define TISCI_MSG_SET_PROC_BOOT_CTRL   0xc101
 #define TISCI_MSG_PROC_AUTH_BOOT_IMIAGE        0xc120
 #define TISCI_MSG_GET_PROC_BOOT_STATUS 0xc400
+#define TISCI_MSG_WAIT_PROC_BOOT_STATUS        0xc401
 
 /**
  * struct ti_sci_msg_hdr - Generic Message Header for All messages and responses
@@ -647,4 +648,52 @@ struct ti_sci_msg_resp_get_proc_boot_status {
        uint32_t status_flags;
 } __packed;
 
+/**
+ * struct ti_sci_msg_req_wait_proc_boot_status - Wait for a processor boot status
+ * @hdr:                       Generic Header
+ * @processor_id:              ID of processor
+ * @num_wait_iterations                Total number of iterations we will check before
+ *                             we will timeout and give up
+ * @num_match_iterations       How many iterations should we have continued
+ *                             status to account for status bits glitching.
+ *                             This is to make sure that match occurs for
+ *                             consecutive checks. This implies that the
+ *                             worst case should consider that the stable
+ *                             time should at the worst be num_wait_iterations
+ *                             num_match_iterations to prevent timeout.
+ * @delay_per_iteration_us     Specifies how long to wait (in micro seconds)
+ *                             between each status checks. This is the minimum
+ *                             duration, and overhead of register reads and
+ *                             checks are on top of this and can vary based on
+ *                             varied conditions.
+ * @delay_before_iterations_us Specifies how long to wait (in micro seconds)
+ *                             before the very first check in the first
+ *                             iteration of status check loop. This is the
+ *                             minimum duration, and overhead of register
+ *                             reads and checks are.
+ * @status_flags_1_set_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 1.
+ * @status_flags_1_set_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 1.
+ * @status_flags_1_clr_all_wait        If non-zero, Specifies that all bits of the
+ *                             status matching this field requested MUST be 0.
+ * @status_flags_1_clr_any_wait        If non-zero, Specifies that at least one of the
+ *                             bits matching this field requested MUST be 0.
+ *
+ * Request type is TISCI_MSG_WAIT_PROC_BOOT_STATUS, response is appropriate
+ * message, or NACK in case of inability to satisfy request.
+ */
+struct ti_sci_msg_req_wait_proc_boot_status {
+       struct ti_sci_msg_hdr hdr;
+       uint8_t processor_id;
+       uint8_t num_wait_iterations;
+       uint8_t num_match_iterations;
+       uint8_t delay_per_iteration_us;
+       uint8_t delay_before_iterations_us;
+       uint32_t status_flags_1_set_all_wait;
+       uint32_t status_flags_1_set_any_wait;
+       uint32_t status_flags_1_clr_all_wait;
+       uint32_t status_flags_1_clr_any_wait;
+} __packed;
+
 #endif /* TI_SCI_PROTOCOL_H */